// pages/addRecipe/addRecipe.js
import {
  addRecipe,
  editRecipe,
  getRecipeDetail
} from '../../../api/recipes';
import {
  store
} from '../../../utils/store';
const app = getApp(); // 获取 app.js 的实例
Page({
  /**
   * 页面的初始数据
   */
  data: {
    id: null, // 菜谱ID，新增时为null
    coverUrl: '', // 封面图,初始为空
    title: '', // 菜谱标题
    description: '', // 美食背后的故事
    ingredients: [{
      name: '', // 食材
      quantity: '' // 用量
    }],
    steps: [{
      stepNumber: 1,
      description: '', //步骤说明
      imageUrl: '' //步骤图片
    },
    {
      stepNumber: 2,
      description: '',
      imageUrl: ''
    }
    ],

    isSubmitting: false, // 提交状态
    userId: null,
    suggestedIngredients: ['姜', '盐', '小葱'], // 建议的食材
    recipeId: null, // 用于存储菜谱ID
    /* 高级设置 */
    showModal: false,
    cookingTimes: ['15分钟左右', '15~30分钟', '30~60分钟', '1小时以上'],
    difficulties: ['零厨艺', '容易做', '有点挑战', '压力略大'],
    categories: [],
    selectedCookingTime: '',
    selectedDifficulty: '',
    selectedCategories: '',
    tips: '',
    servings: '',
    showAdjustModal: false,
    draggingIndex: null,
    activeIndex: -1, // 当前拖拽的索引
    startY: 0, // 拖拽起始位置
    itemHeight: 0, // 单个元素高度
    translateMap: {}, // 所有元素的偏移量映射
    tempPositions: [], // 记录元素原始位置
    showAdjustStepsModal: false,
    activeStepIndex: -1,
    stepTranslateMap: {}
  },

  /**
   * 生命周期函数--监听页面加载
   */
  async onLoad (options) {
    await app.checkLoginStatus();
    // 从页面参数中获取userId
    this.setData({
      userId: options.userId || store.getUserInfo().userId, // 优先使用参数，如果没有则从store获取
      recipeId: options.id || null // 获取菜谱ID,判断是否为编辑模式
    });

    console.log('addRecipe页面，当前用户ID:', this.data.userId);
    console.log('addRecipe页面，当前菜谱ID:', this.data.recipeId);

    if (this.data.recipeId) {
      this.fetchRecipeDetails(this.data.recipeId); // 如果有ID，回显数据
    }
  },

  // 调用API获取菜谱详情(编辑模式回显)
  async fetchRecipeDetails (recipeId) {
    try {
      const res = await getRecipeDetail(recipeId);
      if (res.success) {
        this.setData({
          title: res.data.title || '',
          coverUrl: res.data.coverUrl || '',
          description: res.data.description || '',
          ingredients: res.data.ingredients || [{ name: '', quantity: '' }],
          steps: (res.data.steps || []).map((step, index) => ({
            ...step,
            stepNumber: index + 1 // 确保步骤编号正确
          })),
          tips: res.data.tips || '', // 回显小贴士
          servings: res.data.servings || '', // 回显份量
          selectedCookingTime: res.data.cookTime ? String(res.data.cookTime) : '',
          // 如果存储的是数字（如15），转换为对应的描述
          selectedDifficulty: res.data.difficulty || '', // 回显难度
          selectedCategories: Array.isArray(res.data.categories) ? res.data.categories.join(', ') : '' // 以逗号拼接分类
        });
      } else {
        wx.showToast({ title: res.message || '获取菜谱详情失败', icon: 'none' });
      }
    } catch (error) {
      wx.showToast({ title: '获取菜谱详情失败', icon: 'none' });
    }
  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom () { },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage () { },

  closePage () {
    wx.navigateBack();
  },
  // 更换封面图
  async changeCover () {
    try {
      const res = await wx.chooseMedia({
        count: 1,
        mediaType: ['image'],
        sourceType: ['album', 'camera'],
      });

      if (!res || !res.tempFiles || res.tempFiles.length === 0) {
        console.log('用户取消了选择');
        return; // 用户取消选择，不做任何操作
      }

      const tempFilePath = res.tempFiles[0].tempFilePath;
      this.setData({
        coverUrl: tempFilePath,
      });
    } catch (error) {
      if (error.errMsg.includes('cancel')) {
        console.log('用户取消了选择');
        return; // 用户取消选择，不做任何操作
      }
      wx.showToast({
        title: '选择封面图失败',
        icon: 'none',
      });
    }
  },

  // 添加新的食材行
  addIngredientRow () {
    const ingredients = this.data.ingredients;
    ingredients.push({
      name: '',
      quantity: ''
    });
    this.setData({
      ingredients
    });
  },

  // 更新食材内容
  updateIngredient (e) {
    const {
      index,
      type
    } = e.currentTarget.dataset;
    const {
      value
    } = e.detail;
    const ingredients = this.data.ingredients;
    ingredients[index][type] = value;
    this.setData({
      ingredients
    });
  },

  // 点击建议的食材
  onTapSuggestion (e) {
    const {
      ingredient
    } = e.currentTarget.dataset;
    const ingredients = this.data.ingredients;
    // 找到第一个空的食材输入框
    const emptyIndex = ingredients.findIndex(item => !item.name);
    if (emptyIndex !== -1) {
      ingredients[emptyIndex].name = ingredient;
      this.setData({
        ingredients
      });
    } else {
      // 如果没有空的输入框，就新增一行
      ingredients.push({
        name: ingredient,
        quantity: ''
      });
      this.setData({
        ingredients
      });
    }
  },

  // 调整用料
  openAdjustIngredients () {
    this.setData({
      showAdjustModal: true
    });
    wx.setNavigationBarTitle({
      title: '调整用料'
    });
  },

  closeAdjustModal () {
    this.setData({
      showAdjustModal: false
    });
    wx.setNavigationBarTitle({
      title: ''
    });
  },

  removeIngredient (e) {
    const index = e.currentTarget.dataset.index;
    const ingredients = this.data.ingredients;
    ingredients.splice(index, 1);
    this.setData({
      ingredients
    });
  },

  // 添加新的步骤
  addStep () {
    const steps = this.data.steps;
    steps.push({
      stepNumber: steps.length + 1,
      description: '',
      imageUrl: ''
    });
    this.setData({
      steps
    });
  },

  // 更新步骤说明
  updateStepDescription (e) {
    const {
      index
    } = e.currentTarget.dataset;
    const {
      value
    } = e.detail;
    const steps = this.data.steps;
    steps[index].description = value;
    this.setData({
      steps
    });
  },
  // 处理步骤图片，根据传入的参数，判读单张或者批量
  handleImageSelection (e, count = 1) {
    let index = e?.currentTarget?.dataset?.index; // 仅用于单张替换时
    wx.chooseImage({
      count: count,
      sizeType: ['original', 'compressed'],
      sourceType: ['album', 'camera'],
      success: (res) => {
        const tempFilePaths = res.tempFilePaths;
        let steps = this.data.steps;

        if (index !== undefined) {
          // 单张图片替换
          steps[index].imageUrl = tempFilePaths[0];
        } else {
          // 批量上传
          const firstEmptyIndex = steps.findIndex(step => !step.imageUrl || step.imageUrl.length === 0);

          tempFilePaths.forEach((imagePath, i) => {
            if (firstEmptyIndex !== -1 && i + firstEmptyIndex < steps.length) {
              steps[i + firstEmptyIndex].imageUrl = imagePath;
            } else {
              steps.push({
                stepNumber: steps.length + 1,
                description: '',
                imageUrl: imagePath
              });
            }
          });
        }

        this.setData({ steps });

        wx.showToast({
          title: '添加成功',
          icon: 'success'
        });
      },
      fail: (err) => {
        console.error('选择图片失败：', err);
        wx.showToast({
          title: '选择图片失败',
          icon: 'none'
        });
      }
    });
  },

  // 单张替换调用
  changeStepImage (e) {
    this.handleImageSelection(e, 1);
  },

  // 批量上传调用
  batchUploadImages () {
    this.handleImageSelection(null, 9);
  },

  // 调整步骤
  adjustSteps () {
    if (!this.data.steps) {
      this.setData({
        steps: []
      });
    }

    wx.navigateTo({
      url: '../adjustSteps/adjustSteps?steps=' + encodeURIComponent(JSON.stringify(this.data.steps)),
      fail: (err) => {
        console.error('跳转失败：', err);
        wx.showToast({
          title: '跳转失败',
          icon: 'none'
        });
      }
    });
  },

  // 更新标题
  updateTitle (e) {
    this.setData({
      title: e.detail.value
    });
  },

  // 更新美食故事(描述)
  updateRecipeDesc (e) {
    // 获取输入的值
    const value = e.detail.value;

    // 更新到数据中
    this.setData({
      description: value
    });

    // 可以添加字数提示逻辑
    if (value.length >= 1990) {
      wx.showToast({
        title: '接近字数上限',
        icon: 'none'
      });
    }
  },
  // 验证表单
  validateForm () {
    const {
      title,
      coverUrl,
      ingredients,
      steps
    } = this.data;

    // 验证标题
    if (!title || !title.trim()) {
      wx.showToast({
        title: '请输入菜谱标题',
        icon: 'none'
      });
      return false;
    }

    // 验证封面图（必须）
    if (!coverUrl) {
      wx.showToast({
        title: '请添加封面图',
        icon: 'none'
      });
      return false;
    }

    // 验证食材：至少有一个食材且名称和用量都必填
    const validIngredients = ingredients.filter(
      item => item.name.trim() && item.quantity.trim()
    );
    if (validIngredients.length === 0) {
      wx.showToast({
        title: '请添加食材及用量',
        icon: 'none'
      });
      return false;
    }

    // 验证步骤：至少有一个步骤，且有文字说明或图片
    const validSteps = steps.filter(
      item => item.description.trim() || (item.imageUrl && item.imageUrl.length > 0)
    );
    if (validSteps.length === 0) {
      wx.showToast({
        title: '请至少添加一个步骤',
        icon: 'none'
      });
      return false;
    }

    return true;
  },
  showAdvancedSettings () {
    this.setData({
      showModal: true
    });
    // 动态修改导航栏标题
    wx.setNavigationBarTitle({
      title: '高级设置' // 在模态框显示时设置标题
    });
  },

  closeModal () {
    this.setData({
      showModal: false
    });
    wx.setNavigationBarTitle({
      title: '' // 在模态框关闭时设置标题
    });
  },

  updateTips (e) {
    // 获取输入的值
    const value = e.detail.value;

    // 更新到数据中
    this.setData({
      tips: value
    });

    // 可以添加字数提示逻辑
    if (value.length >= 990) {
      wx.showToast({
        title: '接近字数上限',
        icon: 'none'
      });
    }
  },

  updateServingSize (e) {
    this.setData({
      servings: e.detail.value
    });
  },

  selectCookingTime (e) {
    const value = e.currentTarget.dataset.value;
    this.setData({
      selectedCookingTime: value
    });
  },

  selectDifficulty (e) {
    const value = e.currentTarget.dataset.value;
    this.setData({
      selectedDifficulty: value
    });
  },

  updateCategories (e) {
    this.setData({
      selectedCategories: e.detail.value
    });
  },

  // 发布菜谱(编辑模式下为保存修改)
  // 发布菜谱(编辑模式下为保存修改)
  async publishRecipe () {
    // 防止重复提交
    if (this.data.isSubmitting) return;

    // 表单验证
    if (!this.validateForm()) return;

    try {
      this.setData({ isSubmitting: true });

      // 处理分类字段，支持中文和英文逗号
      const categories = this.data.selectedCategories.split(/,|，/).map(item => item.trim()).filter(item => item);

      wx.showLoading({ title: '上传中...', mask: true });

      // 上传封面图片（如果是本地路径）
      let coverUrl = this.data.coverUrl;
      if (coverUrl && !coverUrl.startsWith('cloud://')) {
        coverUrl = await this.uploadImage(coverUrl);
        this.setData({ coverUrl }); // 确保 UI 也更新
      }


      // 上传步骤图片
      let steps = this.data.steps.map(step => ({ ...step }));
      const uploadTasks = steps
        .filter(step => step.imageUrl && !step.imageUrl.startsWith('cloud://'))
        .map(step => this.uploadImage(step.imageUrl));

      const uploadedUrls = await Promise.all(uploadTasks);

      // 替换原来的本地路径为云端路径
      let uploadIndex = 0;
      steps = steps.map(step => {
        if (step.imageUrl && !step.imageUrl.startsWith('cloud://')) {
          return { ...step, imageUrl: uploadedUrls[uploadIndex++] };
        }
        return step;
      });

      // 组织提交的数据
      const recipeData = {
        recipeId: this.data.recipeId,
        userId: this.data.userId,
        title: this.data.title.trim(),
        coverUrl: coverUrl, // 使用上传后的封面图 URL
        description: this.data.description.trim(),
        ingredients: this.data.ingredients.filter(
          item => item.name.trim() && item.quantity.trim()
        ).map(item => ({
          name: item.name.trim(),
          quantity: item.quantity.trim()
        })),
        steps: steps.filter(item => item.description.trim() || item.imageUrl)
          .map(item => ({
            stepNumber: item.stepNumber,
            description: item.description.trim(),
            imageUrl: item.imageUrl
          })),
        tips: this.data.tips,
        servings: this.data.servings,
        cookTime: this.data.selectedCookingTime,
        difficulty: this.data.selectedDifficulty,
        categories: categories // 处理后的分类数组
      };

      // 调用添加菜谱接口
      if (!this.data.recipeId) {
        await addRecipe(recipeData);
        wx.showToast({ title: '发布成功', icon: 'success' });
      } else {
        const res = await editRecipe(recipeData);
        if (res.success) {
          // 设置编辑成功标记
          wx.setStorageSync('recipeEditSuccess', {
            recipeId: this.data.recipeId,
            timestamp: new Date().getTime()
          });

          // 返回到详情页
          wx.navigateBack({
            delta: 1
          });
        } else {
          wx.showToast({
            title: '修改失败',
            icon: 'none'
          });
        }
      }
    } catch (error) {
      console.error('上传失败：', error);
      wx.showToast({ title: '上传失败，请重试', icon: 'none' });
    } finally {
      wx.hideLoading();
      this.setData({ isSubmitting: false });
    }
  },
  // 上传单张图片到云端
  uploadImage (filePath) {
    return new Promise((resolve, reject) => {
      const cloudPath = `recipes/${Date.now()}-${Math.floor(Math.random() * 1000)}.png`; // 生成唯一文件名

      wx.cloud.uploadFile({
        cloudPath: cloudPath,
        filePath: filePath,
        success: (res) => {
          resolve(res.fileID); // 返回云端 URL
        },
        fail: (err) => {
          console.error('图片上传失败：', err);
          reject(err);
        }
      });
    });
  },

  // 开始拖拽
  startDrag (e) {
    const index = e.currentTarget.dataset.index;
    const touch = e.touches[0];
    if (touch && touch.clientY) {
      const query = wx.createSelectorQuery();
      query.select('.ingredient-edit').boundingClientRect(rect => {
        // 初始化所有元素的原始位置 [y0, y1, y2...]
        const positions = this.data.ingredients.map((_, i) => i * rect.height);
        this.setData({
          activeIndex: index,
          startY: touch.clientY,
          itemHeight: rect.height,
          tempPositions: positions,
          translateMap: {}
        });
      }).exec();
    }
  },

  // 处理拖拽
  handleDrag (e) {
    if (this.data.activeIndex === -1) return;

    const touch = e.touches[0];
    const currentY = touch.clientY;
    const deltaY = currentY - this.data.startY;

    // 更新被拖拽元素的偏移
    this.setData({
      translateMap: {
        [this.data.activeIndex]: deltaY
      }
    });

    // 检查是否需要交换位置
    this.checkSwapCondition(deltaY);
  },

  // 检查交换条件
  checkSwapCondition (deltaY) {
    const {
      activeIndex,
      itemHeight,
      ingredients
    } = this.data;
    const threshold = itemHeight / 2;

    // 计算目标位置
    let targetIndex = activeIndex;
    if (deltaY < -threshold && activeIndex > 0) {
      // 向上拖拽，超过阈值时，交换到上一个位置
      targetIndex = activeIndex - 1;
    } else if (deltaY > threshold && activeIndex < ingredients.length - 1) {
      // 向下拖拽，超过阈值时，交换到下一个位置
      targetIndex = activeIndex + 1;
    }

    // 执行交换
    if (targetIndex !== activeIndex) {
      this.swapItems(activeIndex, targetIndex, deltaY);
    }
  },

  // 交换元素
  swapItems (fromIndex, toIndex, deltaY) {
    const {
      ingredients,
      tempPositions
    } = this.data;

    // 更新数据
    const newIngredients = [...ingredients];
    [newIngredients[fromIndex], newIngredients[toIndex]] = [newIngredients[toIndex], newIngredients[fromIndex]];

    // 更新位置快照
    const newPositions = [...tempPositions];
    [newPositions[fromIndex], newPositions[toIndex]] = [newPositions[toIndex], newPositions[fromIndex]];

    // 计算剩余偏移量
    const remainingOffset = deltaY - (toIndex - fromIndex) * this.data.itemHeight;

    this.setData({
      ingredients: newIngredients,
      tempPositions: newPositions,
      activeIndex: toIndex,
      startY: this.data.startY + (toIndex - fromIndex) * this.data.itemHeight,
      translateMap: {
        [toIndex]: remainingOffset
      }
    });
  },

  // 结束拖拽
  endDrag () {
    const {
      activeIndex,
      translateMap,
      ingredients
    } = this.data;
    const deltaY = translateMap[activeIndex] || 0;

    // 计算最终位置
    let targetIndex = activeIndex;
    if (deltaY < -this.data.itemHeight / 2 && activeIndex > 0) {
      // 向上拖拽，最终交换到上一个位置
      targetIndex = activeIndex - 1;
    } else if (deltaY > this.data.itemHeight / 2 && activeIndex < ingredients.length - 1) {
      // 向下拖拽，最终交换到下一个位置
      targetIndex = activeIndex + 1;
    }

    // 执行最终交换
    if (targetIndex !== activeIndex) {
      this.swapItems(activeIndex, targetIndex, deltaY);
    }

    // 重置状态
    this.setData({
      activeIndex: -1,
      translateMap: {}
    });
  },

  openAdjustSteps () {
    this.setData({
      showAdjustStepsModal: true
    });
    wx.setNavigationBarTitle({
      title: '调整步骤'
    });
  },

  closeAdjustStepsModal () {
    this.setData({
      showAdjustStepsModal: false
    });
    wx.setNavigationBarTitle({
      title: ''
    });
  },

  startStepDrag (e) {
    const index = e.currentTarget.dataset.index;
    const touch = e.touches[0];
    if (touch && touch.clientY) {
      const query = wx.createSelectorQuery();
      query.select('.step-edit').boundingClientRect(rect => {
        const positions = this.data.steps.map((_, i) => i * rect.height);
        this.setData({
          activeStepIndex: index,
          startY: touch.clientY,
          itemHeight: rect.height,
          tempPositions: positions,
          stepTranslateMap: {}
        });
      }).exec();
    }
  },

  handleStepDrag (e) {
    if (this.data.activeStepIndex === -1) return;

    const touch = e.touches[0];
    const currentY = touch.clientY;
    const deltaY = currentY - this.data.startY;

    this.setData({
      stepTranslateMap: {
        [this.data.activeStepIndex]: deltaY
      }
    });

    this.checkStepSwapCondition(deltaY);
  },

  checkStepSwapCondition (deltaY) {
    const {
      activeStepIndex,
      itemHeight,
      steps
    } = this.data;
    const threshold = itemHeight / 2;

    let targetIndex = activeStepIndex;
    if (deltaY < -threshold && activeStepIndex > 0) {
      targetIndex = activeStepIndex - 1;
    } else if (deltaY > threshold && activeStepIndex < steps.length - 1) {
      targetIndex = activeStepIndex + 1;
    }

    if (targetIndex !== activeStepIndex) {
      this.swapSteps(activeStepIndex, targetIndex, deltaY);
    }
  },

  swapSteps (fromIndex, toIndex, deltaY) {
    const {
      steps,
      tempPositions
    } = this.data;

    const newSteps = [...steps];
    [newSteps[fromIndex], newSteps[toIndex]] = [newSteps[toIndex], newSteps[fromIndex]];

    const newPositions = [...tempPositions];
    [newPositions[fromIndex], newPositions[toIndex]] = [newPositions[toIndex], newPositions[fromIndex]];

    const remainingOffset = deltaY - (toIndex - fromIndex) * this.data.itemHeight;

    this.setData({
      steps: newSteps,
      tempPositions: newPositions,
      activeStepIndex: toIndex,
      startY: this.data.startY + (toIndex - fromIndex) * this.data.itemHeight,
      stepTranslateMap: {
        [toIndex]: remainingOffset
      }
    });
  },

  endStepDrag () {
    const {
      activeStepIndex,
      stepTranslateMap,
      steps
    } = this.data;
    const deltaY = stepTranslateMap[activeStepIndex] || 0;

    let targetIndex = activeStepIndex;
    if (deltaY < -this.data.itemHeight / 2 && activeStepIndex > 0) {
      targetIndex = activeStepIndex - 1;
    } else if (deltaY > this.data.itemHeight / 2 && activeStepIndex < steps.length - 1) {
      targetIndex = activeStepIndex + 1;
    }

    if (targetIndex !== activeStepIndex) {
      this.swapSteps(activeStepIndex, targetIndex, deltaY);
    }

    this.setData({
      activeStepIndex: -1,
      stepTranslateMap: {}
    });
  },

  removeStep (e) {
    const index = e.currentTarget.dataset.index;
    const steps = this.data.steps;
    steps.splice(index, 1);
    this.setData({
      steps
    });
  },
})